/*
 * @ProjectName: 编程学习
 * @Copyright:   2019 HangZhou Ashe Dev, Ltd. All Right Reserved.
 * @address:     https://yiyuery.github.io/NoteBooks/
 * @date:        2020/2/23 12:48 下午
 * @description: 本内容仅限于编程技术学习使用，转发请注明出处.
 */
package com.yi.yier.boot.autoconfigure.codegenerator.gen.model.impl;

import com.yi.yier.boot.autoconfigure.codegenerator.common.GenCodeParam;
import com.yi.yier.boot.autoconfigure.codegenerator.common.PropertyConstant;
import com.yi.yier.boot.autoconfigure.codegenerator.gen.AbstractCodeGenerator;
import com.yi.yier.boot.autoconfigure.codegenerator.common.PropertiesLoader;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.*;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *
 * </p>
 *
 * @author Yiyuery
 * @version V1.0.0
 * @date 2020/2/23 12:48 下午
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人}  2020/2/23
 * @modify reason: {方法名}:{原因}
 * ...
 */
@Slf4j
public class DefaultModelGenerator extends AbstractCodeGenerator{

    @Override
    public void genCode(GenCodeParam genCodeParam) {
        Context initConfig = initConfig(genCodeParam);
        List<String> warnings = new ArrayList<>();
        MyBatisGenerator generator = null;
        try {
            Configuration cfg = new Configuration();
            cfg.addContext(initConfig);
            cfg.validate();
            DefaultShellCallback callback = new DefaultShellCallback(true);
            generator = new MyBatisGenerator(cfg, callback, warnings);
            generator.generate(null);
        } catch (Exception e) {
            throw new RuntimeException("Model 和  Mapper 生成失败!", e);
        }

        if (generator == null || generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {
            throw new RuntimeException("Model 和  Mapper 生成失败, warnings: " + warnings);
        }

        if (StringUtils.isEmpty(genCodeParam.getModelName())) {
            genCodeParam.setModelName(tableNameConvertUpperCamel(genCodeParam.getTableName()));
        }

        log.info(genCodeParam.getModelName(), "{}.java 生成成功!");
        log.info(genCodeParam.getModelName(), "{}Mapper.java 生成成功!");
        log.info(genCodeParam.getModelName(), "{}Mapper.xml 生成成功!");
    }

    /**
     * 完善初始化环境
     *
     * @param genCodeParam  表名
     */
    private Context initConfig(GenCodeParam genCodeParam) {
        Context context = null;
        try {
            String exportPath = PropertiesLoader.getProperty(PropertyConstant.YIER_GEN_PROP_EXPORT_PATH);
            if (StringUtils.isEmpty(exportPath)) {
                //未设置导出目录的话默认是项目内生成
                exportPath = PropertiesLoader.getProperty(PropertyConstant.YIER_GEN_PROP_JAVA_RELATIVE);
                //core层代码生成时必须目录存在才可以生成
                File exportFile = Paths.get(exportPath).toFile();
                if (!exportFile.exists()) {
                    exportFile.mkdirs();
                }
            }
            context = initMybatisGeneratorContext(genCodeParam.getSign(), exportPath);
            //生成模型信息  (UserInfoExample.java)-
            JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
            javaModelGeneratorConfiguration.setTargetProject(exportPath);
            javaModelGeneratorConfiguration.setTargetPackage(PropertiesLoader.getProperty(PropertyConstant.YIER_GEN_PROP_PACKAGE_CORE_DAO_MODEL).replace("{sign}", genCodeParam.getSign()));
            javaModelGeneratorConfiguration.addProperty("enableSubPackages", "true");
            context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);

            //生成应用接口
            JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
            javaClientGeneratorConfiguration.setTargetProject(exportPath);
            javaClientGeneratorConfiguration.setTargetPackage(PropertiesLoader.getProperty(PropertyConstant.YIER_GEN_PROP_PACKAGE_CORE_DAO_MAPPER).replace("{sign}", genCodeParam.getSign()));
            javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER");
            javaClientGeneratorConfiguration.addProperty("enableSubPackages", "true");
            javaClientGeneratorConfiguration.addProperty("rootInterface", PropertiesLoader.getProperty(PropertyConstant.YIER_GEN_PROP_REFERENCE_MAPPER_INTERFACE) + "<" + genCodeParam.getModelName() + "," + genCodeParam.getModelName() + "Example>");
            context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);

            //生成表格信息
            TableConfiguration tableConfiguration = new TableConfiguration(context);
            tableConfiguration.setTableName(genCodeParam.getTableName());
            tableConfiguration.setDomainObjectName(genCodeParam.getModelName());
            tableConfiguration.setGeneratedKey(new GeneratedKey("id", "JDBC", true, null));
            context.addTableConfiguration(tableConfiguration);

        } catch (Exception e) {
            throw new RuntimeException("ModelAndMapperGenerator 初始化环境异常!", e);
        }
        return context;
    }
}
